home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pvm34b3.zip / pvm34b3 / pvm3 / examples / gexample.c < prev    next >
C/C++ Source or Header  |  1997-07-22  |  6KB  |  229 lines

  1.  
  2. static char rcsid[] =
  3.     "$Id: gexample.c,v 1.3 1997/07/09 13:24:42 pvmsrc Exp $";
  4.  
  5. /*
  6.  *         PVM version 3.4:  Parallel Virtual Machine System
  7.  *               University of Tennessee, Knoxville TN.
  8.  *           Oak Ridge National Laboratory, Oak Ridge TN.
  9.  *                   Emory University, Atlanta GA.
  10.  *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
  11.  *          G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
  12.  *         P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
  13.  *                   (C) 1997 All Rights Reserved
  14.  *
  15.  *                              NOTICE
  16.  *
  17.  * Permission to use, copy, modify, and distribute this software and
  18.  * its documentation for any purpose and without fee is hereby granted
  19.  * provided that the above copyright notice appear in all copies and
  20.  * that both the copyright notice and this permission notice appear in
  21.  * supporting documentation.
  22.  *
  23.  * Neither the Institutions (Emory University, Oak Ridge National
  24.  * Laboratory, and University of Tennessee) nor the Authors make any
  25.  * representations about the suitability of this software for any
  26.  * purpose.  This software is provided ``as is'' without express or
  27.  * implied warranty.
  28.  *
  29.  * PVM version 3 was funded in part by the U.S. Department of Energy,
  30.  * the National Science Foundation and the State of Tennessee.
  31.  */
  32.  
  33. /* Example of some group function and reduction functions in PVM 
  34.  *
  35.  * 11 March 1994 - Creation by P. Papadopoulos (phil@msr.epm.ornl.gov)
  36.  * 27 June 1997 - updated to allow spmd-style startups for PVM 3.4
  37.  *
  38.  *
  39. */
  40. #include <stdio.h>
  41. #ifdef HASSTDLIB
  42. #include <stdlib.h>
  43. #endif
  44.  
  45. #include "pvm3.h"
  46.  
  47. #define min(u,v) ( (u) < (v) ? (u) : (v) )
  48. #define max(u,v) ( (u) > (v) ? (u) : (v) )
  49.  
  50. #define MATRIXGROUP "matrix"
  51. #define DEFAULT_DIMENSION 100
  52. #define DEFAULT_NPROC     10
  53. #define INITTAG 1000
  54. #define SUMTAG INITTAG + 1
  55. #define PRODTAG SUMTAG + 1
  56. extern void calcprod();
  57. main()
  58. {
  59. int info, mytid, myinst, gsize, nproc = 0;
  60. int maxmax;
  61. int dimension = 0;
  62. int ninst, error;
  63. int tids[32]; int *subblock, *colsum;
  64. double *colprod;
  65. int blksize,nextra,mysrow,i,j,sumsqr,itemp;
  66.  
  67. int *stids;
  68. int spmd = 0;    /* flag to indicate we were started in a spmd-style */
  69. int nsibs; 
  70.  
  71.  
  72.     mytid = pvm_mytid(); /* enroll */
  73.  
  74.     if ((nsibs = pvm_siblings( &stids )) > 1) /* nsibs spawned together */
  75.         spmd = 1;
  76.  
  77.     if( (myinst = pvm_joingroup(MATRIXGROUP)) < 0 )
  78.     {
  79.         pvm_perror( "Could not join group \n" );
  80.         pvm_exit();
  81.         exit( -1 );
  82.     }
  83.     
  84.     if ( myinst == 0 )              
  85.     {
  86.         printf(" This program demonstrates some group and reduction  \n");
  87.         printf(" operations in PVM.  The output displays the \n");
  88.         printf(" the product of the first column of a Toeplitz matrix\n");
  89.         printf(" and the matrix 1-norm. The matrix data is distributed \n");
  90.         printf(" among several processors.  The Toeplitz matrix is \n"); 
  91.         printf(" symmetric with the first row being the row \n");
  92.         printf(" vector [1 2 ... n].\n");
  93.         if ( !spmd && pvm_parent() == PvmNoParent )
  94.         {
  95.             while ( nproc <= 0 || nproc > 32 || dimension <= 0)
  96.             {
  97.                 printf( " Input dimension ( >0 ) of matrix: " );
  98.                 scanf( "%d", &dimension );
  99.                 printf( " Input number of tasks (1-32): " );
  100.                 scanf( "%d", &nproc );
  101.             }
  102.         }
  103.         else
  104.         {
  105.             nproc = DEFAULT_NPROC;
  106.             dimension = DEFAULT_DIMENSION;
  107.         }
  108.  
  109.         if (!spmd && nproc > 1) 
  110.         {
  111.             ninst = pvm_spawn( "gexample", (char **) 0, 0, "",  
  112.                     nproc-1, tids);  
  113.             nproc = min (nproc, ninst + 1); 
  114.         }
  115.  
  116.         if (spmd) 
  117.             nproc = nsibs;
  118.  
  119.         pvm_initsend( PvmDataDefault );
  120.         pvm_pkint( &nproc, 1, 1 );
  121.         pvm_pkint( &dimension, 1, 1 );
  122.         if (spmd)
  123.             pvm_mcast(stids, nsibs, INITTAG);
  124.         else
  125.             pvm_mcast( tids, nproc - 1, INITTAG ); 
  126.  
  127.         printf("\n       --> Using %d processors <-- \n\n", nproc);
  128.     }
  129.  
  130.     else /* other nodes receive the number of processors from  0 */
  131.     {
  132.         pvm_recv( -1, INITTAG );
  133.         pvm_upkint( &nproc, 1, 1 );
  134.         pvm_upkint( &dimension, 1, 1);
  135.     }
  136.  
  137.     /* Make the group static. freezegroup will wait until nproc tids have
  138.         joined the group.                  */
  139.  
  140.     info = pvm_freezegroup(MATRIXGROUP,nproc);
  141.  
  142.     /* Map matrix rows to processors --      */ 
  143.  
  144.     blksize =  dimension/nproc ;
  145.     nextra =   dimension % nproc; 
  146.  
  147.     if( myinst < nextra ) 
  148.     {
  149.         mysrow = (blksize + 1) * myinst;  
  150.         blksize++; 
  151.     }
  152.     else
  153.         mysrow = (blksize + 1)*(nextra) + blksize*(myinst - nextra);
  154.  
  155.     subblock = (int *) calloc(blksize*dimension,sizeof(int)); 
  156.     colsum   = (int *) calloc(dimension,sizeof(int));
  157.     colprod  = (double *) calloc(dimension,sizeof(double));
  158.  
  159.     if (mysrow >= dimension)    /* too many processors ! */
  160.         blksize = 0;
  161.  
  162.     /* Assign data to this subblock.  The entries below make the entire matrix
  163.         a symmetric Toeplitz matrix (i.e. diagonals are of constant value)  */
  164.  
  165.     for (i = 0; i < blksize; i++)
  166.         for (j = 0; j < dimension; j++)
  167.             *(subblock + i*dimension + j) = 1 + abs(mysrow + i - j); 
  168.  
  169.     /* Locally compute the sum of each column and put into colsum */
  170.     for (j = 0; j < dimension; j++)
  171.     {
  172.         colsum[j] = 0;
  173.         colprod[j] = 1.0;
  174.     }
  175.  
  176.     for (i = 0; i < blksize; i ++)
  177.         for(j = 0; j < dimension; j++)
  178.         {
  179.             itemp = *(subblock + j + i*dimension);
  180.             colsum[j] += abs( itemp );
  181.             colprod[j] *= abs( itemp );
  182.         }
  183.  
  184.     /* synchronize the computation and then reduce using pvm_sum. This gives
  185.         a row vector that has the all the columns sums  */
  186.  
  187.     if ( pvm_reduce(PvmSum,colsum,dimension,PVM_INT,SUMTAG,
  188.             MATRIXGROUP,0) < 0  )
  189.         pvm_perror( "pvm_reduce had an error \n") ; 
  190.  
  191.     pvm_reduce(calcprod,colprod,dimension,PVM_DOUBLE,PRODTAG,
  192.         MATRIXGROUP,0); 
  193.  
  194.     if( myinst == 0)
  195.     {
  196.         maxmax = 0;
  197.         for (j = 0; j < dimension; j++)
  198.             maxmax = max(colsum[j],maxmax);
  199.  
  200.         printf(" The 1-Norm is %d  \n" , maxmax );
  201.         printf(" ( Should be the sum of the integers from 1 to %d )\n", 
  202.                 dimension );
  203.         printf(" The product of column 1 is %g  \n" , colprod[0] );
  204.         printf(" ( Should be %d factorial)\n", dimension);
  205.     }
  206.  
  207.     info = pvm_barrier(MATRIXGROUP,-1);  /* make sure processes are finished*/
  208.     if (info < 0) 
  209.         printf("Barrier failed with result code %d\n", info);
  210.  
  211.     pvm_lvgroup(MATRIXGROUP);
  212.  
  213.     free(subblock); free(colsum); free(colprod); 
  214.     pvm_exit();
  215. }
  216.  
  217.  
  218. /*** A User-defined Reduction Function ***/
  219. void
  220. calcprod(datatype,x,y,num,info)
  221. int *datatype;
  222. double  *x,*y;
  223. int *num, *info;
  224. {
  225. int i;
  226.     for (i = 0 ; i < *num; i++)
  227.         x[i] *= y[i];
  228. }        
  229.